package com.glsc.ngateway.platform.controller;

import com.glsc.ngateway.common.api.platform.dto.user.PlatformUserDto;
import com.glsc.ngateway.common.api.platform.dto.user.UrlDto;
import com.glsc.ngateway.common.api.platform.resp.PlatformResponse;
import com.glsc.ngateway.common.base.annotation.PageAccessAnnotation;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.Url;
import com.glsc.ngateway.common.base.exception.PlatformException;
import com.glsc.ngateway.platform.aspect.UserCache;
import com.glsc.ngateway.platform.service.UrlService;
import com.glsc.ngateway.platform.utils.JsonTool;
import com.glsc.ngateway.platform.utils.SpecificationFactory;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import static com.glsc.ngateway.common.api.common.enums.DictConstant.ROLE_OPEARATOR;

/**
 * 功能描述: <br>
 *
 * @author gaojc
 * @date 2020/9/3 14:37
 */
@RestController
@RequestMapping("/url")
public class UrlController {

    private UrlService urlService;
    private UserCache userCache;
    private HttpServletRequest request;

    @Autowired
    public void setUrlService(UrlService urlService) {
        this.urlService = urlService;
    }

    @Autowired
    public void setUserCache(UserCache userCache) {
        this.userCache = userCache;
    }

    @Autowired
    public void setRequest(HttpServletRequest request) {
        this.request = request;
    }

    @PageAccessAnnotation(operMenu = "权限管理-菜单管理", operType = "新建", operDesc = "新增菜单")
    @PostMapping("/create")
    @ApiOperation(value = "新增权限")
    public PlatformResponse<Void> create(@RequestBody Url url) {
        urlService.addUrl(url);
        return PlatformResponse.successMsg("创建成功");
    }

    @PageAccessAnnotation(operMenu = "权限管理-菜单管理", operType = "编辑", operDesc = "编辑菜单")
    @PostMapping("/update")
    @ApiOperation(value = "更新权限信息")
    public PlatformResponse<Void> update(@RequestBody Url url) {
        urlService.update(url);
        return PlatformResponse.successMsg("更新成功");
    }

    @PageAccessAnnotation(operMenu = "权限管理-菜单管理", operType = "删除", operDesc = "删除菜单")
    @PostMapping("/delete")
    @ApiOperation(value = "删除权限")
    public PlatformResponse<Void> delete(@RequestBody String uid) {
        Long id = JsonTool.parseJsonId(uid);
        if (id == null) {
            return PlatformResponse.failedMsg("id不能为空");
        }
        if (urlService.delete(id) == 1) {
            return PlatformResponse.successMsg("删除成功");
        } else {
            return PlatformResponse.failedMsg("未找到id=" + id + "的权限");
        }
    }

    @GetMapping("/findbyid")
    @ApiOperation(value = "根据id查找权限")
    public PlatformResponse<Url> findById(@RequestParam("id") long id) {
        Url url = urlService.findById(id);
        if (url == null) {
            return PlatformResponse.failedMsg("未找到id=" + id + "的权限");
        }
        return PlatformResponse.successData(url);
    }

    @PageAccessAnnotation(operMenu = "权限管理-菜单管理", operType = "列表", operDesc = "菜单列表")
    @GetMapping("/list")
    @ApiOperation(value = "查询所有权限")
    public PlatformResponse<List<UrlDto>> list() {
        List<Url> list = urlService.findAll();
        Map<Long, UrlDto> idMap = new HashMap<>();
        for (Url url : list) {
            Long id = url.getId();
            Long parentId = url.getParentId() == null ? 0 : url.getParentId();
            boolean exist = idMap.keySet().contains(id);
            UrlDto dto = exist ? idMap.get(id) : new UrlDto();
            dto.setKey(url.getId());
            dto.setValue(url.getId());
            dto.setTitle(url.getName());
            dto.setPath(url.getPath());
            dto.setUrl(url.getUrl());
            dto.setParentId(parentId);
            if (!exist) {
                idMap.put(id, dto);
            }
            if (!idMap.keySet().contains(parentId)) {
                UrlDto parentDto = new UrlDto();
                parentDto.setKey(parentId);
                List<UrlDto> childList = new ArrayList<>();
                childList.add(dto);
                parentDto.setChildren(childList);
                idMap.put(parentId, parentDto);
            } else {
                UrlDto parentDto = idMap.get(parentId);
                if (parentDto.getChildren() == null) {
                    parentDto.setChildren(new ArrayList<>());
                }
                parentDto.getChildren().add(dto);
            }
        }
        UrlDto root = idMap.get(Long.valueOf(0));
        AtomicInteger total = new AtomicInteger(0);
        setLevel(root, 0, total);
        if (total.get() < idMap.size()) {
            throw PlatformException.error("权限表中存在循环");
        }

        String username = userCache.getOpNo(request);
        PlatformUserDto user = userCache.get(request);
        Set<String> userRoleNames = new HashSet<>(user.getRoles());

        List<UrlDto> ret = root.getChildren();
        if (!"admin".equals(username) || !userRoleNames.contains(ROLE_OPEARATOR)) {
            ret = ret.stream().filter(dto -> !"/systemMgr".equals(dto.getPath()))
                    .filter(dto -> !"/systemRun".equals(dto.getPath()))
                    .collect(Collectors.toList());
        }
        return PlatformResponse.successData(ret);
    }

    private void setLevel(UrlDto dto, int level, AtomicInteger total) {
        if (dto != null) {
            if (dto.getLevel() > 0) {
                throw PlatformException.error("权限表中存在循环");
            }
            dto.setLevel(level);
            total.incrementAndGet();
            if (dto.getChildren() != null && !dto.getChildren().isEmpty()) {
                for (UrlDto child : dto.getChildren()) {
                    setLevel(child, level + 1, total);
                }
            }
        }
    }

    @GetMapping("/listpage")
    @ApiOperation(value = "查询权限分页")
    public PlatformResponse<Page<Url>> listpage(
            @ApiParam(value = "url") @RequestParam(required = false) String url,
            @ApiParam(value = "接口名称") @RequestParam(required = false) String name,
            @ApiParam(value = "页码从1开始") @RequestParam(required = false) Integer pageNo,
            @ApiParam(value = "每页显示条数 默认10") @RequestParam(required = false) Integer pageSize) {
        if (url != null && url.isEmpty()) {
            url = null;
        }
        if (name != null && name.isEmpty()) {
            name = null;
        }
        SpecificationFactory.SpecElement deletedE = new SpecificationFactory.SpecElement(SpecificationFactory.Type.EQ, "deleted", 0);
        SpecificationFactory.SpecElement urlE = new SpecificationFactory.SpecElement(SpecificationFactory.Type.EQ, "url", url);
        SpecificationFactory.SpecElement nameE = new SpecificationFactory.SpecElement(SpecificationFactory.Type.LIKE, "name", name);
        Specification spec = SpecificationFactory.build(SpecificationFactory.OP.AND, deletedE, urlE, nameE);

        if (pageNo == null || pageNo < 1) {
            pageNo = 1;
        }
        if (pageSize == null || pageSize < 1) {
            pageSize = 10;
        }

        Page<Url> page = urlService.findPage(spec, pageNo, pageSize);
        return PlatformResponse.successData(page);
    }

    @PostMapping("/addRolesByAuths")
    @ApiOperation(value = "为多个权限批量设置角色")
    public PlatformResponse<Void> addRolesByAuthId(@ApiParam(required = true, value = "{\"authIds\": [1, 2, 3], \"roleIds\": [1, 2, 3]}")
                                                      @RequestBody Map<String, List<Long>> map) {
        List<Long> authIds = map.get("authIds");
        List<Long> roleIds = map.get("roleIds");
        if(authIds==null || authIds.size()==0){
            return PlatformResponse.failedMsg("权限ID不能为空！");
        }
        if(roleIds==null || roleIds.size()==0){
            return PlatformResponse.failedMsg("角色ID不能为空！");
        }
        urlService.addRoles(authIds.stream()
                        .map(id -> Long.valueOf(String.valueOf(id)))
                        .collect(Collectors.toList()),
                roleIds.stream()
                        .map(id -> Long.valueOf(String.valueOf(id)))
                        .collect(Collectors.toList()));
        return PlatformResponse.successMsg("添加成功");
    }

    @PostMapping("/deleteRolesByAuths")
    @ApiOperation(value = "为多个权限批量删除角色")
    public PlatformResponse<Void> deleteRolesByAuthId(@ApiParam(required = true, value = "{\"authIds\": [1, 2, 3], \"roleIds\": [1, 2, 3]}")
                                                         @RequestBody Map<String, List<Long>> map) {
        List<Long> authIds = map.get("authIds");
        List<Long> roleIds = map.get("roleIds");
        if(authIds==null || authIds.size()==0){
            return PlatformResponse.failedMsg("权限ID不能为空！");
        }
        if(roleIds==null || roleIds.size()==0){
            return PlatformResponse.failedMsg("角色ID不能为空！");
        }
        urlService.deleteRoles(
                authIds.stream()
                        .map(id -> Long.valueOf(String.valueOf(id)))
                        .collect(Collectors.toList()),
                roleIds.stream()
                        .map(id -> Long.valueOf(String.valueOf(id)))
                        .collect(Collectors.toList()));
        return PlatformResponse.successMsg("删除成功");
    }

}
